﻿// Copyright (c) Microsoft Corporation.  All rights reserved.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using EnvDTE80;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using System.IO;

namespace QuickSolutionStartPageControl
{
    /// <summary>
    /// Interaction logic for MyControl.xaml
    /// </summary>
    public partial class MyControl : UserControl
    {
        public MyControl()
        {
            InitializeComponent();
        }

        public int Year { get; set; }

        private bool _loaded = false;
        public bool DoTextChanged = true;
        private volatile int _ignoreCharCount = 0;
        List<myObject> _myObjects = new List<myObject>();

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (!_loaded)
            {
                _loaded = true;
                lblStatus.Content = "Scanning Folder...";
                gridProjects.Visibility = System.Windows.Visibility.Hidden;
                lblStatus.Visibility = System.Windows.Visibility.Visible;
                BackgroundWorker bw = new BackgroundWorker();
                bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
                bw.WorkerReportsProgress = true;
                bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
                bw.RunWorkerAsync(Year);
            }
        }

        void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            lblStatus.Content = e.UserState.ToString();            
        }

        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (_myObjects == null || _myObjects.Count == 0)
                ((TabItem)this.Parent).Visibility = System.Windows.Visibility.Hidden;
            else
            {
                lstProjects.ItemsSource = _myObjects;
                lblStatus.Visibility = System.Windows.Visibility.Hidden;
                gridProjects.Visibility = System.Windows.Visibility.Visible;
                Filter(txtFilter.Text);
            }
        }

        void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            if (!Directory.Exists(@"C:\Development\" + e.Argument))
                e.Result = null;
            else
            {
                ((BackgroundWorker)sender).ReportProgress(0, "Scanning for solutions");
                _ignoreCharCount = (@"C:\Development\" + e.Argument).Length;
                LoadDirectorySolution(new DirectoryInfo(@"C:\Development\" + e.Argument));
                ((BackgroundWorker)sender).ReportProgress(0, "Sorting solutions");
                myObject[] solutions = _myObjects.ToArray();
                Array.Sort(solutions, (f1, f2) => f1.DisplayName.CompareTo(f2.DisplayName));
                _myObjects.Clear();
                _myObjects.AddRange(solutions);
            }
        }

        public void LoadDirectorySolution(DirectoryInfo di)
        {
            bool found = false;
            foreach (FileInfo fi in di.GetFiles("*.sln", SearchOption.TopDirectoryOnly))
            {
                found = true;
                _myObjects.Add(new myObject()
                {
                    DisplayName = fi.Name,
                    FullPath = fi.FullName,
                    DisplayPath = fi.FullName.Remove(0, _ignoreCharCount)
                });
            }
            if (!found)
            {
                foreach (DirectoryInfo d in di.GetDirectories())
                {
                    LoadDirectorySolution(d);
                }
            }
        }

        private StartPageSettings _settings;
        /// <summary>
        /// Return a StartPageSettings object.
        ///
        /// Use: StartPageSettings.StoreString("MySettingName", "MySettingValue");
        /// Use: string value = StartPageSettings.RetrieveString("MySettingName");
        ///
        /// Note: As this property is using the Start Page tool window DataContext to retrieve the Visual Studio DTE, 
        /// this property can only be used after the UserControl is loaded and the inherited DataContext is set.
        /// </summary>
        private StartPageSettings StartPageSettings
        {
            get
            {
                if (_settings == null)
                {
                    DTE2 dte = Utilities.GetDTE(DataContext);
                    ServiceProvider serviceProvider = Utilities.GetServiceProvider(dte);
                    _settings = new StartPageSettings(serviceProvider);
                }
                return _settings;
            }
        }

        private void OpenSolution_Click(object sender, RoutedEventArgs e)
        {
            Button btn = (Button)sender;
            string path = btn.CommandParameter.ToString();
            if (!File.Exists(path))
            {
                MessageBox.Show("This Solution is missing");
            }
            else
            {
                ServiceProvider serviceProvider = new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)Utilities.GetDTE(DataContext));
                IVsSolution solution = serviceProvider.GetService(typeof(SVsSolution)) as IVsSolution;

                solution.OpenSolutionFile((uint)__VSSLNOPENOPTIONS.SLNOPENOPT_Silent, path);
            }
        }

        private class myObject
        {
            public string DisplayName { get; set; }
            public string FullPath { get; set; }
            public string DisplayPath { get; set; }
        }

        public void TextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (DoTextChanged)
            {
                DoTextChanged = false;
                Filter(txtFilter.Text);
                DoTextChanged = true;
                if (TextChanged != null)
                {
                    TextChanged(txtFilter.Text);
                }
            }
        }

        public void Filter(string newText)
        {
            txtFilter.Text = newText;
            List<myObject> obj = new List<myObject>();
            string searchText = newText.ToLower();
            foreach (myObject mo in _myObjects)
            {
                if (mo.DisplayPath.ToLower().Contains(searchText))
                {
                    obj.Add(mo);
                }
            }
            lstProjects.ItemsSource = obj;
        }

        public delegate void TextChangedDelegate(string newText);

        public event TextChangedDelegate TextChanged;
    }
}
